/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.kipme.ws;

import java.net.MalformedURLException;
import org.kipme.connectors.DepartmentWSConnector;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.XMLGregorianCalendar;
import org.kipme.connectors.DatabaseConnector;
import org.kipme.department.*;
import org.kipme.entities.Departmentdescription;
import org.kipme.entities.Magazinedproducts;
import org.kipme.entities.Orderedproducts;
import org.kipme.entities.Orders;

/**
 *
 * @author Nyion
 */
@WebService(serviceName = "HeadquarterWS")
public class HeadquarterWS {
//    @WebServiceRef(wsdlLocation = "WEB-INF/wsdl/212.51.216.71_8080/KipmeClientWS/service/central.wsdl")
//    CentralService_Service service;
    
    /**
     * This is a sample web service operation
     */
    @WebMethod(operationName = "hello")
    public String hello() {
        return "Hello!";
    }

    /**
     * Pobiera podst. informacje o przedmiotach jakie posiada oddzial
     */
    @WebMethod(operationName = "getDepartmentProductsInfo")
    public java.util.List<org.kipme.department.ProductInfo> getDepartmentProductsInfo() throws MalformedURLException {
        
        java.util.List<org.kipme.department.ProductInfo> response = DepartmentWSConnector.getProductInfo();
        
        return response;
    }
    
    @WebMethod(operationName = "getDepartmentProductByCode")
    public Product getDepartmentProductByCode(@WebParam(name = "productCode") String productCode) {
        Product response = null;
        
        try{
            response = DepartmentWSConnector.getProductByProductCode(productCode);
        }
        catch(Exception ex){
            
        }
        
        return response;
    }

    @WebMethod(operationName = "getDepartmentProductsByType")
    public List<Product> getDepartmentProductsByType(@WebParam(name = "type") String type) throws MalformedURLException {
        
        List<Product> response = DepartmentWSConnector.getProductsByType(type);
        
        return response;
    }
        
    @WebMethod(operationName = "getDepartmentProductsByCategory")
    public List<Product> getDepartmentProductsByCategory(@WebParam(name = "category") String category) throws MalformedURLException {
        
        List<Product> response = DepartmentWSConnector.getProductsByCategory(category);
        
        return response;
    }
    
    @WebMethod(operationName = "getDepartmentProductsByTypeAndCategory")
    public List<Product> getDepartmentProductsByTypeAndCategory(@WebParam(name = "type") String type, @WebParam(name = "categoryCode") String categoryCode) throws MalformedURLException {
        
        List<Product> response = new ArrayList<Product>(); 
        List<Product> temporary = DepartmentWSConnector.getProductsByType(type);
        
        for (int i = 0; i < temporary.size(); i++) {
            if(categoryCode.compareTo(temporary.get(i).getCategory().getCategoryCode()) == 0){
                response.add(temporary.get(i));
            }
        }
        
        return (List<Product>)response;
    }
    
    /**
     * Web service operation
     */
    @WebMethod(operationName = "addProductToMagazine")
    public String addProductToMagazine(@WebParam(name = "amount") int amount, @WebParam(name = "name") String name, @WebParam(name = "typ") String typ, @WebParam(name = "kategoria") String kategoria, @WebParam(name = "opis") String opis) {
        
        Magazinedproducts newProduct = new Magazinedproducts(name, typ, kategoria, amount, opis);
        
        DatabaseConnector.AddEntity(newProduct);
        
        return newProduct.toString();
    }

    /**
     * Web service operation
     */
    @WebMethod(operationName = "removeProductFromMagazine")
    public String removeProductFromMagazine(@WebParam(name = "productId") int productId, @WebParam(name = "amount") int amount) {
        
        Magazinedproducts product = DatabaseConnector.GetProductById(productId);
        
        if(amount == 0){
            DatabaseConnector.RemoveEntity(product);
        }
        else{
            product.setAmount(product.getAmount() - amount);
            DatabaseConnector.EditEntity(product);
        }
        
        return product.toString();
    }

    /**
     * Web service operation
     */
    @WebMethod(operationName = "getMagazinedProducts")
    public List<Magazinedproducts> getMagazinedProducts() {
        List<Magazinedproducts> list = DatabaseConnector.GetAllProducts();
        
        return list;
    }

    @WebMethod(operationName = "changeMagazinedProductAmount")
    public Magazinedproducts changeMagazinedProductAmount(@WebParam(name = "productCode") String productCode, @WebParam(name = "newAmount") int newAmount) {
        
        if(newAmount < 0){
            newAmount = 0;
        }
        
        Magazinedproducts product = DatabaseConnector.GetProductByProductCode(productCode);
        
        if(product != null){
            product.setAmount(newAmount);
            DatabaseConnector.EditEntity(product);
        }
        
        return product;
    }

    /**
     * Web service operation
     */
    @WebMethod(operationName = "getMagazinedProductsByCode")
    public Magazinedproducts getMagazinedProductsByCode(@WebParam(name = "productCode") String productCode) {
        Magazinedproducts response = DatabaseConnector.GetProductByProductCode(productCode);
        
        return response;
    }
    
    @WebMethod(operationName = "getMagazinedProductsByType")
    public List<Magazinedproducts> getMagazinedProductsByType(@WebParam(name = "typ") String typ) {
        List<Magazinedproducts> list = DatabaseConnector.GetProductsByTyp(typ);
        
        return list;
    }
    
    @WebMethod(operationName = "getMagazinedProductsByCategory")
    public List<Magazinedproducts> getMagazinedProductsByCategory(@WebParam(name = "kategoria") String kategoria) {
        List<Magazinedproducts> list = DatabaseConnector.GetProductsByCategory(kategoria);
        
        return list;
    }
    
    @WebMethod(operationName = "getMagazinedProductsByTypeAndCategory")
    public List<Magazinedproducts> getMagazinedProductsByTypeAndCategory(@WebParam(name = "typ") String typ, @WebParam(name = "category") String category) {
        List<Magazinedproducts> list = DatabaseConnector.GetProductsByTypAndCategory(typ, category);
        
        return list;
    }
    
    @WebMethod(operationName = "getCategories")
    public List<Category> getCategories() throws MalformedURLException {
        Category none = new Category();
        none.setCategoryCode("none");
        none.setName("None");
        List<Category> response = DepartmentWSConnector.getCategoryList();
        response.add(none);
        return response;
    }
    
    @WebMethod(operationName = "getProductTypes")
    public List<ProductType> getProductTypes() throws MalformedURLException {
        ProductType none = new ProductType();
        none.setTypeCode("none");
        none.setName("None");
        List<ProductType> response = DepartmentWSConnector.getProductTypeList();
        response.add(none);
        return response;
    }
    
    @WebMethod(operationName = "getAllOrderStatuses")
    public List<String> getAllOrderStatuses() {
        
        List<String> response = new ArrayList<String>();
        
        response.add(OrderStatus.COMPLETED.toString());
        response.add(OrderStatus.EXPECTANT.toString());
        response.add(OrderStatus.RECEIVED.toString());
        response.add(OrderStatus.REPORTED.toString());
        response.add(OrderStatus.UNAVAILABLE.toString());
        response.add(OrderStatus.ERROR.toString());
        
        return response;
    }
    
    @WebMethod(operationName = "getDepartmentOrders")
    public List<Order> getDepartmentOrders() throws BusinessException_Exception, MalformedURLException {
        List<Order> response = null;
        response = DepartmentWSConnector.checkWaitingOrders();
        
        if(response != null || response.size() > 0){
            for (int i = 0; i < response.size(); i++) {
                Order order = response.get(i);
                Orders newOrder = new Orders(order.getOrderId(), order.getDate().toGregorianCalendar().getTime(), new Date(), new Integer(0));
                DatabaseConnector.AddEntity(newOrder);
                for (int j = 0; j < order.getProducts().size(); j++) {
                    ProductOrder productOrder = order.getProducts().get(i);
                    if(DatabaseConnector.CheckIfProductExistsByProductCode(productOrder.getProductId())){
                        //Orderedproducts(Orders order, String productcode, Integer amount, String orderstatus)
                        Orderedproducts orderedProducts = new Orderedproducts(newOrder.getId(), productOrder.getProductId(), new Integer(productOrder.getNumberOfProduct()), productOrder.getStatus().toString());
                        DatabaseConnector.AddEntity(orderedProducts);
                        productOrder.setStatus(OrderStatus.RECEIVED);
                    }
                    else{
                        Product prod = DepartmentWSConnector.getProductByProductCode(productOrder.getProductId());
                        if(prod != null){
                            Magazinedproducts magProd = new Magazinedproducts(prod.getName(), prod.getType().toString(), prod.getCategory().toString(), 0, prod.getDescribe());
                            Orderedproducts orderedProducts = new Orderedproducts(newOrder.getId(), magProd.getProductcode(), 0, OrderStatus.UNAVAILABLE.toString());
                            DatabaseConnector.AddEntity(magProd);
                            DatabaseConnector.AddEntity(orderedProducts);
                            productOrder.setStatus(OrderStatus.RECEIVED);
                        }
                        else{
                            ///////////////////////////
                            /// PROBLEM BRAKU ITEMA ///
                            ///////////////////////////
//                            uwzględnić możliwość błędnego zamówienia przedmiotów,
//                            które nie istnieją i automatycznie wysyłać do oddziału 
//                            odpowiedź, która zawiera { ilośćProduktów = 0,
//                            statusZamówienia = ERROR, komentarz = „Przedmiot nie istnieje” },
//                            a te, które istnieją prowadzić normalnym trybem
                            productOrder.setStatus(OrderStatus.ERROR);
                            productOrder.setComment("Przedmiot nie istnieje");
                            productOrder.setNumberOfProduct(0);
                        }
                    }
                }
                
                DepartmentWSConnector.updateOrderState(order);
            }
        }
        
        return response;
    }
    
    @WebMethod(operationName = "getDepartmentOrdersTest")
    public List<Order> getDepartmentOrdersTest() {
//        List<Order> response = null;
//        try{
//        response = DepartmentWSConnector.checkWaitingOrders();
//        }
//        catch(Exception ex){
//            
//        }
        
        return null;
    }
    
    @WebMethod(operationName = "getSavedOrders")
    public List<org.kipme.entities.Orders> getSavedOrders() {
        List<org.kipme.entities.Orders> response = DatabaseConnector.GetAllOrders();
        
        return response;
    }
    
    @WebMethod(operationName = "getSavedOrdersByDate")
    public List<Orders> getSavedOrdersByDate(@WebParam(name = "startDateExclude") Date startDate, @WebParam(name = "endDateExclude") Date endDate) {
        List<Orders> response = DatabaseConnector.GetOrdersByDate(startDate, endDate);
        
        return response;
    }
    
    @WebMethod(operationName = "getOrderedProducts")
    public List<Orderedproducts> getOrderedProducts(@WebParam(name = "orderId") int orderId) {
        List<Orderedproducts> response = DatabaseConnector.GetOrderedProducts(orderId);
        
        return response;
    }
    
    @WebMethod(operationName = "changeOrderedProductStatus")
    public Orderedproducts changeOrderedProductStatus(@WebParam(name = "orderId") int orderId, @WebParam(name = "productCode") String productCode, @WebParam(name = "newStatus") String newStatus) throws Exception {
        Orderedproducts response = DatabaseConnector.GetOrderedProductByCode(orderId, productCode);
        
        if(OrderStatus.fromValue(newStatus) == OrderStatus.COMPLETED){
            Magazinedproducts product = DatabaseConnector.GetProductByProductCode(productCode);
            if(product.getAmount() >= response.getAmount()){
                response.setOrderstatus(newStatus);
            }
            else{
                throw new Exception("Za mało produktów w magazynie by uznac zamowienie za zakonczone");
            }
        }
        else{
            response.setOrderstatus(newStatus);
        }
        
        DatabaseConnector.EditEntity(response);
        
        return response;
    }
    
    @WebMethod(operationName = "sendOrderUpdateToDepartment")
    public Order sendOrderUpdateToDepartment(@WebParam(name = "departmentOrderId") String departmentOrderId) throws BusinessException_Exception, DatatypeConfigurationException, MalformedURLException {
        Order response = null;
        
        List<Order> departmentOrders = DepartmentWSConnector.checkWaitingOrders();
        
        if(departmentOrders != null || departmentOrders.size() > 0){
            for (int i = 0; i < departmentOrders.size(); i++) {
                if(departmentOrderId.compareTo(departmentOrders.get(i).getOrderId()) == 0){
                    response = departmentOrders.get(i);
                    break;
                }
            }

            Orders usOrder = DatabaseConnector.GetOrdersByDepartmentOrderId(departmentOrderId);

            for (int i = 0; i < response.getProducts().size(); i++) {
                ProductOrder productOrder = response.getProducts().get(i);
                Orderedproducts orderedPorduct = DatabaseConnector.GetOrderedProductByCode(usOrder.getId(), productOrder.getProductId());
                Magazinedproducts magProduct = DatabaseConnector.GetProductByProductCode(orderedPorduct.getProductcode());
                magProduct.setAmount(magProduct.getAmount() - orderedPorduct.getAmount());
                productOrder.setStatus(OrderStatus.fromValue(orderedPorduct.getOrderstatus()));
            }
            
            DepartmentWSConnector.updateOrderState(response);
        }
        else{
            Orders orders = DatabaseConnector.GetOrdersByDepartmentOrderId(departmentOrderId);
            DatabaseConnector.RemoveEntity(orders);
        }
        
        
        return response;
    }
    
    @WebMethod(operationName = "getDepartmentTransactionSummary")
    public List<Transaction> getDepartmentTransactionSummary() throws MalformedURLException {
        return DepartmentWSConnector.getTransactionSummary();
    }
    
    @WebMethod(operationName = "getDepartmentTransactionsByDate")
    public List<Transaction> getDepartmentTransactions(@WebParam(name = "startDate") XMLGregorianCalendar startDate, @WebParam(name = "endDate") XMLGregorianCalendar endDate) throws MalformedURLException {
        return DepartmentWSConnector.getTransactions(startDate, endDate);
    }
    
    @WebMethod(operationName = "getDepartmentTransactionsByCode")
    public List<Transaction> getDepartmentTransactionsByCode(@WebParam(name = "productCode") java.lang.String productCode) throws MalformedURLException {
        return DepartmentWSConnector.getTransactionsByProductCode(productCode);
    }
    
    @WebMethod(operationName = "addNewDepartment")
    public Departmentdescription addNewDepartment(@WebParam(name = "name") String name, @WebParam(name = "url") String url) throws MalformedURLException, Exception {
        boolean udaloSie = true;
        Departmentdescription response = null;
        try{
            DepartmentWSConnector.SetNewWSDLLocation(url);
        }
        catch(Exception ex){
            Departmentdescription department = DatabaseConnector.GetDepartmentById(DepartmentWSConnector.getFocusedDepartmentId());

            DepartmentWSConnector.SetNewWSDLLocation(department.getUrl());
            
            udaloSie = false;
            
            throw new Exception("Niewłaściwy adres url!");
        }
        
        if(udaloSie){
            response = new Departmentdescription(name, url);
            DatabaseConnector.AddEntity(response);
        }
        return response;
    }
    
    @WebMethod(operationName = "getAllDepartments")
    public List<Departmentdescription> getAllDepartments() {
        List<Departmentdescription> response = DatabaseConnector.GetAllDepartments();
        
        return response;
    }
    
    @WebMethod(operationName = "removeDepartment")
    public Departmentdescription removeDepartment(@WebParam(name = "id") int id) {
        Departmentdescription response = DatabaseConnector.GetDepartmentById(id);
        
        DatabaseConnector.RemoveEntity(response);
        
        return response;
    }
    
    @WebMethod(operationName = "setFocusOnDepartment")
    public Departmentdescription setFocusOnDepartment(@WebParam(name = "id") int id) throws MalformedURLException, Exception {
        Departmentdescription response = DatabaseConnector.GetDepartmentById(id);
        
        DepartmentWSConnector.SetNewWSDLLocation(response.getUrl());
        DepartmentWSConnector.setFocusedDepartmentId(id);
        
        return response;
    }
    
}
